package com.zenithmind.library.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zenithmind.library.pojo.domain.AuthorStatistics;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.math.BigDecimal;

/**
 * 作者统计Mapper接口
 * 遵循接口隔离原则：只包含统计相关的数据访问方法
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Mapper
public interface AuthorStatisticsMapper extends BaseMapper<AuthorStatistics> {

    /**
     * 根据作者ID查询统计信息
     * 
     * @param authorId 作者ID
     * @return 统计信息
     */
    @Select("SELECT * FROM lib_author_statistics WHERE author_id = #{authorId} AND deleted = 0")
    AuthorStatistics selectByAuthorId(@Param("authorId") String authorId);

    /**
     * 增加作品数量
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "book_count = book_count + 1, " +
            "last_publish_time = NOW(), " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int incrementBookCount(@Param("authorId") String authorId);

    /**
     * 减少作品数量
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "book_count = book_count - 1, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND book_count > 0 AND deleted = 0")
    int decrementBookCount(@Param("authorId") String authorId);

    /**
     * 增加借阅次数
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "total_borrow_count = total_borrow_count + 1, " +
            "current_borrow_count = current_borrow_count + 1, " +
            "last_borrow_time = NOW(), " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int incrementBorrowCount(@Param("authorId") String authorId);

    /**
     * 减少当前借阅次数
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "current_borrow_count = current_borrow_count - 1, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND current_borrow_count > 0 AND deleted = 0")
    int decrementCurrentBorrowCount(@Param("authorId") String authorId);

    /**
     * 增加评价
     * 
     * @param authorId 作者ID
     * @param isPositive 是否好评
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "total_review_count = total_review_count + 1, " +
            "positive_review_count = positive_review_count + #{isPositive}, " +
            "negative_review_count = negative_review_count + #{isNegative}, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int addReview(@Param("authorId") String authorId, 
                  @Param("isPositive") Integer isPositive, 
                  @Param("isNegative") Integer isNegative);

    /**
     * 移除评价
     * 
     * @param authorId 作者ID
     * @param wasPositive 是否为好评
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "total_review_count = total_review_count - 1, " +
            "positive_review_count = positive_review_count - #{wasPositive}, " +
            "negative_review_count = negative_review_count - #{wasNegative}, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND total_review_count > 0 AND deleted = 0")
    int removeReview(@Param("authorId") String authorId, 
                     @Param("wasPositive") Integer wasPositive, 
                     @Param("wasNegative") Integer wasNegative);

    /**
     * 更新平均评分
     * 
     * @param authorId 作者ID
     * @param averageRating 平均评分
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "average_rating = #{averageRating}, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int updateAverageRating(@Param("authorId") String authorId, @Param("averageRating") BigDecimal averageRating);

    /**
     * 增加收藏次数
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "favorite_count = favorite_count + 1, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int incrementFavoriteCount(@Param("authorId") String authorId);

    /**
     * 减少收藏次数
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "favorite_count = favorite_count - 1, " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND favorite_count > 0 AND deleted = 0")
    int decrementFavoriteCount(@Param("authorId") String authorId);

    /**
     * 重新计算作品数量
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "book_count = (SELECT COUNT(*) FROM lib_book_author ba " +
            "               INNER JOIN lib_book b ON ba.book_id = b.id " +
            "               WHERE ba.author_id = #{authorId} AND ba.deleted = 0 AND b.deleted = 0), " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int recalculateBookCount(@Param("authorId") String authorId);

    /**
     * 重新计算总借阅次数
     * 
     * @param authorId 作者ID
     * @return 更新行数
     */
    @Update("UPDATE lib_author_statistics SET " +
            "total_borrow_count = (SELECT COALESCE(SUM(bs.total_borrow_count), 0) " +
            "                      FROM lib_book_author ba " +
            "                      INNER JOIN lib_book_statistics bs ON ba.book_id = bs.book_id " +
            "                      WHERE ba.author_id = #{authorId} AND ba.deleted = 0 AND bs.deleted = 0), " +
            "update_time = NOW() " +
            "WHERE author_id = #{authorId} AND deleted = 0")
    int recalculateTotalBorrowCount(@Param("authorId") String authorId);
}
